﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Web;
using Data.UserDb;

namespace Data.UserDb
{
    public class ShopRepository
    {
        private readonly UserAccountContext _db = new UserAccountContext("Data Source=122.224.167.244,1433;Initial Catalog=UserAccount;Persist Security Info=True;User ID=sa;Password=fangm@781124");

        #region [UserAccount]

        /// <summary>
        /// 获取用户帐务信息
        /// </summary>
        /// <param name="usrId">用户id</param>
        /// <returns>用户帐号信息</returns>
        public Account GetAccount(Int64 usrId)
        {
            var account = _db.Account.SingleOrDefault(acc => acc.UId == usrId);
            return account ;
        }

        /// <summary>
        ///更新帐号信息
        /// </summary>
        /// <param name="usrid">用户id</param>
        /// <param name="username">用户名</param>
        /// <param name="name">用户昵称</param>
        /// <param name="transType">业务类型</param>
        /// <param name="orderId">订单号</param>
        /// <param name="amount">提交数量</param>
        /// <param name="note">备注说明</param>
        /// <returns>帐号信息</returns>
        public Account UpdateAccount(Int64 usrid, String username, String name, TransactionType transType, String orderId, Int32 amount, String note)
        {
            var account = GetAccount(usrid);
            if(account == null)
            {
                account = new Account
                           {
                               Amount = 0,
                               CreateTime = DateTime.Now,
                               Name = name,
                               UId = usrid,
                               UpdateTime = DateTime.Now,
                               UserName = username
                           };
                Add(account);
                Save();
            }
            
            
            account.Amount += amount;

            if(account.Amount < 0) throw new Exception("余额不足");

            //增加日志
            AddTransLog(transType, account.UId, account.UserName, null, null, orderId, amount, note);

            account.UpdateTime = DateTime.Now;

            return account;
        }

        /// <summary>
        /// 增加帐号信息
        /// </summary>
        /// <param name="acc">新增帐号</param>
        public void Add(Account acc)
        {
            _db.Account.InsertOnSubmit(acc);
        }


        private void AddTransLog(TransactionType transType, Int64 usrid, String usrName, Int64? fromUsrId, String fromUsrName, String orderId, Int32 amount, String note)
        {
            var log = _db.TransLogs.SingleOrDefault(l => l.OrderId == orderId);
            if (log != null) throw new Exception(String.Format("该订单号{0}已经处理,处理时间:{1}", log.OrderId, log.CreateTime));

            log = new TransLogs
                      {
                          Amount = amount,
                          CreateTime = DateTime.Now,
                          FromUserId = fromUsrId,
                          FromUserName = fromUsrName,
                          Note = note,
                          OrderId = orderId,
                          TransTypeId = transType.TransTypeId,
                          TransTypeName = transType.TransTypeName,
                          UserId = usrid,
                          UserName = usrName
                      };
            _db.TransLogs.InsertOnSubmit(log);
        }

        #endregion

        #region [SHOP Items]

        /// <summary>
        /// 获取销售中的物品
        /// </summary>
        /// <returns></returns>
        public IQueryable<Items> GetOnSaleItems()
        {
            return from item in _db.Items where item.OnSale == true orderby item.CreateDate descending select item;
        }

        /// <summary>
        /// 获取物品详细信息
        /// </summary>
        /// <param name="itemId">物品Id</param>
        /// <returns>物品信息</returns>
        public Items GetItemDetail(Int64 itemId)
        {
            return _db.Items.SingleOrDefault(i => i.ItemId == itemId);
        }

        /// <summary>
        /// 通过分类获取物品列表
        /// </summary>
        /// <param name="cateId">分类Id</param>
        /// <returns></returns>
        public IQueryable<Items> GetItemByCategory(Int32 cateId)
        {
            return from item in _db.Items
                   where item.CategoryId == cateId && item.OnSale == true
                   orderby item.CreateDate descending
                   select item;
        }

        /// <summary>
        /// 通过服务类型获取物品列表
        /// </summary>
        /// <param name="srvId"></param>
        /// <returns></returns>
        public IQueryable<Items> GetItemBySrvId(Int32 srvId)
        {
            return from item in _db.Items
                   where item.SrvId == srvId && item.OnSale == true && item.Storage >0
                   orderby item.CreateDate descending
                   select item;
        }

        public IQueryable<Items> GetAllItems()
        {
            return from item in _db.Items orderby item.ItemId descending select item;
        }

        #endregion

        #region [Buy Item]
        
        /// <summary>
        /// 购买物品
        /// </summary>
        /// <param name="itemId">物品ID</param>
        /// <param name="usrId">用户ID</param>
        /// <param name="toUserId">赠送对象用户ID</param>
        /// <returns>返回订单对象</returns>
        public Orders Buy(Int64 itemId, Int32 usrId, Int32 toUserId)
        {
            var item = _db.Items.SingleOrDefault(i => i.ItemId == itemId);

            if (item == null) throw new Exception("错误的商品ID");
            if(!item.OnSale.Value) throw new Exception("该商品已经不能购买");
            if (item.Storage < 1) throw new Exception("该商品已经售光");
            
            var order = new Orders
                            {
                                Amount = item.TotalAmount.HasValue ? item.TotalAmount.Value : 0,
                                UserId = usrId,
                                ToUserId = toUserId,
                                CreateTime = DateTime.Now,
                                ItemId = item.ItemId,
                                ItemName = item.ItemName,
                                PayStatus = 0,
                                Price = item.Price,
                                TotalPrice = item.Price,
                                SrvId = item.SrvId,
                                SrvStatus = 0
                            };

            CreateOrder(order);
            --item.Storage;
            Save();

            return order;
        }
        

        #endregion

        #region [Order Info]

        public Orders GetOrder(Int64 orderId)
        {
            return _db.Orders.SingleOrDefault(o => o.OrderId == orderId);
        }

        public void CreateOrder(Orders order)
        {
            _db.Orders.InsertOnSubmit(order);
        }

        #endregion


        #region [Category Info]

        /// <summary>
        /// 获取分类信息
        /// </summary>
        /// <param name="cateid"></param>
        /// <returns></returns>
        public ItemCategory GetCategoryById(Int32 cateid)
        {
            return _db.ItemCategory.SingleOrDefault(c => c.CateId == cateid);
        }

        /// <summary>
        /// 获取所有分类
        /// </summary>
        /// <returns></returns>
        public IQueryable<ItemCategory> GetAllCategory()
        {
            return from c in _db.ItemCategory orderby c.OrderId descending select c;
        }


        #endregion


        public void AddBox(Orders order)
        {
            var box = _db.Box.SingleOrDefault(c => c.ItemType == order.ItemId&& c.UsrID == order.ToUserId);
            if (box == null)
            {
                box = new Box
                          {
                              Amount = 1,
                              ItemType = (int)order.ItemId,
                              UpdateTime = DateTime.Now,
                              UsrID = (int)order.ToUserId
                          };
                _db.Box.InsertOnSubmit(box);
            }
            else
                box.Amount++;

        }


        /// <summary>
        /// 提交数据变化
        /// </summary>
        public void Save()
        {
            _db.SubmitChanges();
        }

        public TransactionType GetTransType(Int32 typeid)
        {
            return _db.TransactionType.SingleOrDefault(t => t.TransTypeId == typeid);
        }

        public IQueryable<ItemCategory> GetCategoryBySrvId(Int32 srvId)
        {
            return from c in _db.ItemCategory where c.SrvId == srvId select c;
        }


        public void CreateItem(Items item)
        {
            _db.Items.InsertOnSubmit(item);
        }


        #region Summary Orders

        public IQueryable<OrderSummary> SummaryByDate(DateTime startDate, DateTime endDate, Int32 srvId)
        {
            return from order in _db.Orders
             where order.PayStatus == 1 && order.SrvId == srvId && order.CreateTime >= startDate && order.CreateTime < endDate.AddDays(1)
             group order by order.CreateTime.Value.Date
             into o select new OrderSummary{Date = o.Key, Count = o.Count(), InComing = o.Sum(c=>c.Price)};
        }

        public IQueryable<OrderSummary> SumVipByDate(DateTime startDate, DateTime endDate)
        {
            return SummaryByDate(startDate, endDate, 2);
        }

        public IQueryable<OrderSummary> SumRoomByDate(DateTime startDate, DateTime endDate)
        {
            return SummaryByDate(startDate, endDate, 1);
        }

        public IQueryable<OrderSummary> SumAll(DateTime startDate, DateTime endDate)
        {
            return from order in _db.Orders
                   where order.PayStatus == 1 && (order.SrvId==1 || order.SrvId==2) && order.CreateTime >= startDate && order.CreateTime < endDate.AddDays(1)
                   group order by order.CreateTime.Value.Date
                       into o
                       select new OrderSummary { Date = o.Key, Count = o.Count(), InComing = o.Sum(c => c.Price) };
        }
        #endregion
    }

    public class OrderSummary
    {
        public DateTime Date { get; set; }
        public Int32 Count { get; set; }
        public Int32 InComing { get; set; }
    }

    public static class PagerExtenion
    {
        /// <summary>
        /// 分页扩展程序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="pages"></param>
        /// <returns></returns>
        public static IQueryable<T> Page<T>(this IQueryable<T> source, Int32 pageIndex, Int32 pageSize, out Int32 pages) 
        {
            var recordCount = source.Count();
            pages = recordCount%pageSize == 0 ? recordCount/pageSize:recordCount/pageSize + 1;

            return source.Skip((pageIndex + 1)*pageSize).Take(pageSize);
        }


    }
}
